-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

local lu = require 'luaunit'
local ncsi_core = require 'ncsi.ncsi_core'
local ncsi_comm = require 'ncsi.ncsi_comm'
local datas = require 'network_adapter.datas'
local mc_utils = require 'mc.utils'
local c_network_adapter_db = require 'network_adapter.db'
local ncsi_service = require 'ncsi.ncsi_service'
local signal = require 'mc.signal'
local c_ncsi_nc_info = require 'ncsi.ncsi_ncinfo'
local c_ncsi_info = require 'ncsi.ncsi_info'
TEST_ncsi_eth = {}
local cwd = mc_utils.realpath('.')

function TEST_ncsi_eth:test_ncsi_clib_call()
    ret = ncsi_core.ncsi_get_log(1,"eth:0","",1)
    lu.assertEquals(ret, false)
end

function TEST_ncsi_eth:setUp()
    local test_db_path = cwd .. '/network_adapter.test.db'
    mc_utils.remove_file(test_db_path)
    self.database = c_network_adapter_db(test_db_path, datas)
    ncsi_comm.ncsi_wait_eth_interface_up = function ()
        return false
    end
end

function TEST_ncsi_eth:tearDown()
    local test_db_path = cwd .. '/network_adapter.test.db'
    mc_utils.remove_file(test_db_path)
    self.database.db:close()
end

function TEST_ncsi_eth:test_ncsi_port_basic_init()
    ncsi_comm.get_instance():ncsi_port_basic_init(self.database, 0, 'eth0')
    ncsi_comm.get_instance().ncsi_channel_cnt = 1
    ncsi_comm.get_instance():ncsi_basic_init(self.database)
    local ncsi_channel_cnt = ncsi_core.get_ncsi_channel_cnt()
    lu.assertEquals(ncsi_channel_cnt, 4)
end

function TEST_ncsi_eth:test_set_ncsi_ethid_task()
    local NcsiNCInfo = {
        Id = 1,
        NcsiEthId = 1,
        __rowid = 1
    }
    c_ncsi_nc_info.db = self.database
    ncsi_service.db = self.database
    c_ncsi_nc_info.collection:add_object(NcsiNCInfo)
    local ret = pcall(ncsi_service.set_ncsi_ethid_task, ncsi_service)
    lu.assertEquals(ret, true)
    local nc_info = ncsi_service.db:select(ncsi_service.db.NcsiNCInfo):first()
    lu.assertEquals(nc_info.EthId, 1)
end

function TEST_ncsi_eth:test_register_signal_change_method()
    ncsi_service.ncsi_info = {
        sig_multi_vlan_added = signal.new(),
        sig_eth_intf_add = signal.new(),
        sig_vlan_info_changed = signal.new(),
        sig_mac_addr_changed = signal.new(),
        ncsi_info_init = function ()
            return nil
        end,
        ncsi_uptade_link_status = function ()
            return nil
        end
    }
    ncsi_service.ncsi_comm = {
        sig_relink_ncsi_port = signal.new(),
        sig_update_link_status = signal.new(),
        ncsi_sync_eth_mac = function ()
            return nil
        end,
        ncsi_init = function ()
            return nil
        end,
        ncsi_set_vlan_info = function ()
            return nil
        end,
        ncsi_basic_init = function ()
            return nil
        end,
        ncsi_update_multi_vlan = function ()
            return nil
        end
    }
    local ok = pcall(ncsi_service.register_signal_change_method, ncsi_service)
    lu.assertEquals(ok, true)
    ok = pcall(ncsi_service.ncsi_info.sig_mac_addr_changed.emit,ncsi_service.ncsi_info.sig_mac_addr_changed)
    lu.assertEquals(ok, true)
    ok = pcall(ncsi_service.ncsi_info.sig_eth_intf_add.emit,ncsi_service.ncsi_info.sig_eth_intf_add)
    lu.assertEquals(ok, true)
    ok = pcall(ncsi_service.ncsi_info.sig_vlan_info_changed.emit,ncsi_service.ncsi_info.sig_vlan_info_changed)
    lu.assertEquals(ok, true)
    ok = pcall(ncsi_service.ncsi_info.sig_multi_vlan_added.emit,ncsi_service.ncsi_info.sig_multi_vlan_added)
    lu.assertEquals(ok, true)
    ok = pcall(ncsi_service.ncsi_comm.sig_relink_ncsi_port.emit,ncsi_service.ncsi_comm.sig_relink_ncsi_port)
    lu.assertEquals(ok, true)
    ok = pcall(ncsi_service.ncsi_comm.sig_update_link_status.emit,ncsi_service.ncsi_comm.sig_update_link_status)
    lu.assertEquals(ok, true)
end

function TEST_ncsi_eth:test_set_eth_mac_addr()
    local c_ncsi_info_b = c_ncsi_info
    c_ncsi_info.db = {
        select = function (ncsi_info_obj)
            return {
                first = function ()
                    return {
                        Mac = '20:22:01:59:28:3E',
                        save = function() end
                    }
                end
            }
        end,
        NcsiNCInfo = {}
    }

    c_ncsi_info.ncsi_get_eth_obj = function()
        return {
            Mac = '20:22:01:59:28:3E'
        }
    end

    c_ncsi_info.sig_mac_addr_changed = {
        emit = function() end
    }

    local obj = c_ncsi_info.db:select(c_ncsi_info.db.NcsiNCInfo):first()
    lu.assertEquals(obj.Mac, '20:22:01:59:28:3E')
    c_ncsi_info.set_eth_mac_addr(c_ncsi_info, '20:22:01:59:28:3B')
    lu.assertEquals(obj.Mac, '20:22:01:59:28:3E')

    c_ncsi_info = c_ncsi_info_b
end

function TEST_ncsi_eth:test_nc_info_init_1()
    local c_ncsi_info_b = c_ncsi_info
    c_ncsi_info.db = {
        select = function (self, db_table)
            if db_table == 'NcsiNCInfo' then
                return {
                    first = function ()
                        return {
                            Mac = '20:22:01:59:28:4D',
                            save = function() end
                        }
                    end
                }
            end
            if db_table == 'NcsiNCPortInfo' then
                return {
                    where = function()
                        return {
                            first = function ()
                                return {
                                    PortId = 7,
                                    save = function() end
                                }
                        end}
                    end
                }
            end
            return {
                first = function ()
                    return {
                        save = function() end
                    }
                end
            }
        end,
        NcsiNCInfo = 'NcsiNCInfo',
        NcsiNCPortInfo = 'NcsiNCPortInfo'
    }

    c_ncsi_info.ncsi_get_eth_obj = function()
        return {
            Mac = '20:22:01:59:28:3E',
            VlanState = true,
            VlanId = 4094
        }
    end

    local obj = c_ncsi_info.db:select(c_ncsi_info.db.NcsiNCInfo):first()
    lu.assertEquals(obj.Mac, '20:22:01:59:28:4D')
    c_ncsi_info:ncsi_nc_info_init()
    lu.assertEquals(obj.Mac, '20:22:01:59:28:4D')

    c_ncsi_info = c_ncsi_info_b
end

function TEST_ncsi_eth:test_nc_info_init_2()
    local c_ncsi_info_b = c_ncsi_info
    local NcsiNCInfo_t = {
        save = function() end
    }
    c_ncsi_info.db = {
        select = function (self, db_table)
            if db_table == 'NcsiNCInfo' then
                return {
                    first = function (self)
                        return NcsiNCInfo_t
                    end
                }
            end
            if db_table == 'NcsiNCPortInfo' then
                return {
                    where = function()
                        return {
                            first = function ()
                                return {
                                    PortId = 7,
                                    save = function() end
                                }
                        end}
                    end
                }
            end
            return {
                first = function ()
                    return {
                        save = function() end
                    }
                end
            }
        end,
        NcsiNCInfo = 'NcsiNCInfo',
        NcsiNCPortInfo = 'NcsiNCPortInfo'
    }

    c_ncsi_info.ncsi_get_eth_obj = function()
        return {
            Mac = '20:22:01:59:28:3E',
            VlanState = true,
            VlanId = 4094
        }
    end

    local obj = c_ncsi_info.db:select(c_ncsi_info.db.NcsiNCInfo):first()
    lu.assertEquals(obj.Mac, nil)
    c_ncsi_info:ncsi_nc_info_init()
    lu.assertEquals(obj.Mac, '20:22:01:59:28:3E')

    c_ncsi_info = c_ncsi_info_b
end

function TEST_ncsi_eth:test_nc_info_init_3()
    local c_ncsi_info_b = c_ncsi_info
    local NcsiNCInfo_t = {
        Mac = '00:00:00:00:00:00',
        save = function() end
    }
    c_ncsi_info.db = {
        select = function (self, db_table)
            if db_table == 'NcsiNCInfo' then
                return {
                    first = function (self)
                        return NcsiNCInfo_t
                    end
                }
            end
            if db_table == 'NcsiNCPortInfo' then
                return {
                    where = function()
                        return {
                            first = function ()
                                return {
                                    PortId = 7,
                                    save = function() end
                                }
                        end}
                    end
                }
            end
            return {
                first = function ()
                    return {
                        save = function() end
                    }
                end
            }
        end,
        NcsiNCInfo = 'NcsiNCInfo',
        NcsiNCPortInfo = 'NcsiNCPortInfo'
    }

    c_ncsi_info.ncsi_get_eth_obj = function()
        return {
            Mac = '20:22:01:59:28:3E',
            VlanState = true,
            VlanId = 4094
        }
    end

    local obj = c_ncsi_info.db:select(c_ncsi_info.db.NcsiNCInfo):first()
    lu.assertEquals(obj.Mac, '00:00:00:00:00:00')
    c_ncsi_info:ncsi_nc_info_init()
    lu.assertEquals(obj.Mac, '20:22:01:59:28:3E')

    c_ncsi_info = c_ncsi_info_b
end